<template>
  <el-form
    border
    label-width="100px"
    ref="ruleFormRef"
    :model="spuInfo"
    :rules="rules"
  >
    <el-form-item label="SPU名称" prop="spuName">
      <el-input type="text" placeholder="SPU名称" v-model="spuInfo.spuName" />
    </el-form-item>
    <el-form-item label="品牌" prop="tmId">
      <el-select placeholder="请选择" v-model="spuInfo.tmId">
        <el-option
          v-for="tm in trademarkList"
          :key="tm.id"
          :label="tm.tmName"
          :value="tm.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" prop="description">
      <el-input
        type="textarea"
        placeholder="SPU名称"
        rows="4"
        v-model="spuInfo.description"
      />
    </el-form-item>
    <el-form-item label="SPU图片" prop="spuImageList">
      <template #default>
        <el-upload     
          v-model:file-list="spuInfo.spuImageList"
          :action="`${BASE_URL}/admin/product/upload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </template>
    </el-form-item>
    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select
        v-model="spuInfo.spuSaleAttr"
        :placeholder="saleAtrrPlaceholder"
      >
        <el-option
          v-for="bs in fileterBaseSaleAttrList"
          :key="bs.id"
          :label="bs.name"
          :value="bs.name"
        ></el-option>
      </el-select>
      <el-button
        :icon="Plus"
        type="primary"
        @click="addSaleAttr(spuInfo.spuSaleAttr)"
        >添加销售属性</el-button
      >
      <el-table border :data="spuInfo.spuSaleAttrList" style="margin-top: 15px">
        <el-table-column
          label="序号"
          type="index"
          width="80px"
          align="center"
        ></el-table-column>
        <el-table-column
          label="属性名"
          width="160px"
          prop="saleAttrName"
        ></el-table-column>
        <el-table-column label="属性值列表">
          <template v-slot="{ row, $index }">
            <el-tag
              style="margin-right: 5px"
              v-for="tag in row.spuSaleAttrValueList"
              :key="tag"
              class="mx-1"
              closable
              :disable-transitions="false"
              @close="handleClose(row, tag)"
            >
              {{ tag.saleAttrValueName }}
            </el-tag>
            <el-input
              placeholder="名称"
              style="width: 100px"
              v-if="row.isShowInput"
              ref="InputRef"
              v-model="inputValue"
              class="ml-1 w-20"
              size="small"
              @keyup.enter="handleInputConfirm"
              @blur="handleInputConfirm(row, $index)"
            />
            <el-button
              v-else
              :icon="Plus"
              size="small"
              @click="addSaleAttrValue(row, $index)"
            ></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="160px">
          <template v-slot="{ row, $index }">
            <el-button
              size="small"
              :icon="Delete"
              type="danger"
              @click="deleteAddSaleAttr($index)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm(ruleFormRef)"
        >保存</el-button
      >
      <el-button @click="emits('getScene', 1)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
export default {
  name: 'SpuForm',
}
</script>

<script lang="ts" setup>
import { ref, onMounted, reactive, computed, nextTick } from 'vue'
import type { UploadProps, FormRules, FormInstance } from 'element-plus'
import { ElMessage, ElInput } from 'element-plus'
import { Plus, Delete } from '@element-plus/icons-vue'
import {
  reqGetTrademarkList,
  reqGetBaseSaleAttrList,
  reqSaveSpu,
  reqSpuImgListData,
  reqSpuSaleAttrList,
  reqUpdateSpuInfo,
} from '@/api/product/spu'
import { useCategoryStore } from '@/stores/category'

const categoryStore = useCategoryStore()
const BASE_URL = import.meta.env.VITE_API_URL
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const trademarkList = ref([])
const baseSaleAttrList = ref([])
const props = defineProps(['spu'])
const spuInfo = reactive({
  spuName: '', // 输入的spu名称
  tmId: '', //spu品牌id
  description: '',
  spuSaleAttr: '', //销售属性筛选框选中时显示的内容
  category3Id: '',
  spuImageList: [], //存储spu图片
  spuSaleAttrList: [], //基本销售属性
  ...props.spu,
})

const emits = defineEmits(['getScene'])

//表单校验桂规则
const ruleFormRef = ref<FormInstance>()
const rules = reactive<FormRules>({
  spuName: [
    {
      type: 'string',
      required: true,
      message: '请输入SPU名称',
      trigger: 'blur',
      transform(value) {
        return value.trim()
      },
    },
    {
      min: 1,
      max: 10,
      message: 'SPU名称长度请设置为1到10个字符内',
      trigger: 'blur',
    },
  ],
  tmId: [
    {
      type: 'number',
      required: true,
      message: '请选择SPU品牌',
      trigger: 'change',
    },
  ],
  description: [
    {
      type: 'string',
      required: true,
      message: '请输入SPU描述',
      trigger: 'blur',
      transform(value) {
        return value.trim()
      },
    },
  ],
  spuImageList: [
    {
      type: 'array',
      required: true,
      message: '请上传SPU图片',
      trigger: 'blur',
    },
  ],
  spuSaleAttrList: [
    {
      type: 'array',
      required: true,
      message: '请添加销售属性及其属性值',
      trigger: 'change',
      transform(value) {
        const everyHasSaleValue = value.every((item) => {
          return item.spuSaleAttrValueList.length !== 0
        })
        return everyHasSaleValue ? value : []
      },
    },
  ],
})

//组件挂载时获取销售属性列表和品牌列表
onMounted(async () => {
  try {
    const id = spuInfo.id
    let promises = [reqGetTrademarkList(), reqGetBaseSaleAttrList()]
    if (id) {
      promises = promises.concat([
        reqSpuImgListData(id),
        reqSpuSaleAttrList(id),
      ])
    }
    const [
      responseTrademarkList,
      responseBaseSaleAttrList,
      responseSpuImgList,
      responseSpuSaleAttrList,
    ] = await Promise.all(promises)
    trademarkList.value = responseTrademarkList
    baseSaleAttrList.value = responseBaseSaleAttrList
    if (responseSpuImgList && responseSpuSaleAttrList) {
      spuInfo.spuImageList = responseSpuImgList.map((item) => {
        return {
          ...item,
          name: item.imgName,
          url: item.imgUrl,
        }
      })
      spuInfo.spuSaleAttrList = responseSpuSaleAttrList
    }
  } catch (error) {
    ElMessage.error('获取属性失败...')
  }
})

const fileterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((item) => {
    return !spuInfo.spuSaleAttrList.find((saleAttr) => {
      return saleAttr.saleAttrName === item.name
    })
  })
})

//销售属性的placeholder显示内容
const saleAtrrPlaceholder = computed(() => {
  return fileterBaseSaleAttrList.value.length
    ? '还有' + fileterBaseSaleAttrList.value.length + '个未选择'
    : '没有啦！'
})

// 0、图片上传前执行格式校验
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  const imgType = ['image/jpeg', 'image/jpg', 'image/png']
  if (!imgType.includes(rawFile.type)) {
    ElMessage.error('请上传jpeg/jpg/png格式的图片!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片的大小不能超过2MB!')
    return false
  }
  return true
}

// 1、图片上传成功，给spuImageList中传值
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile,
  uploadFiles
) => {
  uploadFile.url = response.data
  ruleFormRef.value?.clearValidate(['spuImageList'])
}

//2、删除图片时修改spuImageList
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  spuInfo.spuImageList = uploadFiles
  console.log(spuInfo)
}

//3、图片预览要执行的操作
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

//4、添加属事件
const addSaleAttr = () => {
  if (!spuInfo.spuSaleAttr) return
  const spuSaleAttrList = spuInfo.spuSaleAttrList
  if (
    spuSaleAttrList.length &&
    spuSaleAttrList.some((item) => item.spuSaleAttrValueList.length === 0)
  ) {
    ElMessage.error('属性值不能为空，请添加')
    spuInfo.spuSaleAttr = ''
    return
  }
  const id = baseSaleAttrList.value.find(
    (item) => item.name == spuInfo.spuSaleAttr
  ).id

  spuInfo.spuSaleAttrList.push({
    baseSaleAttrId: id,
    saleAttrName: spuInfo.spuSaleAttr,
    isShowInput: false,
    spuSaleAttrValueList: [],
  })
  spuInfo.spuSaleAttr = ''
}

// 5、添加属性值事件
const addSaleAttrValue = (row, index) => {
  row.isShowInput = true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}

// 属性值相关参数
const inputValue = ref('')
const InputRef = ref<InstanceType<typeof ElInput>>()

// 6、删除单个属性值事件
const handleClose = (row, tag: string) => {
  row.spuSaleAttrValueList.splice(row.spuSaleAttrValueList.indexOf(tag), 1)
}

// 7、输入属性的属性值成功的事件
const handleInputConfirm = (row) => {
  row.isShowInput = false
  if (!inputValue.value.trim()) {
    inputValue.value = ''
    return
  }
  if (inputValue.value) {
    if (
      row.spuSaleAttrValueList.find(
        (item) => item.saleAttrValueName === inputValue.value
      )
    ) {
      ElMessage.error('属性值不能重复...')
      inputValue.value = ''
      return
    }
    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      saleAttrName: row.saleAttrName, // 当前属性名称 比如 颜色 版本 尺寸
      saleAttrValueName: inputValue.value, // 具体的属性值
    })
  }
  inputValue.value = ''
}

// 8、删除单个属性的函数
const deleteAddSaleAttr = (index) => {
  spuInfo.spuSaleAttrList.splice(index, 1)
  if (
    spuInfo.spuSaleAttrList.every((item) => {
      return item.spuSaleAttrValueList.length !== 0
    })
  ) {
    ruleFormRef.value?.clearValidate(['spuSaleAttrList'])
  }
}

// 9、提交表单事件
const submitForm = async (formEl: FormInstance | undefined) => {
  console.log(formEl, 111)
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      spuInfo.category3Id = categoryStore.category3Id
      spuInfo.spuImageList = spuInfo.spuImageList.map((item) => {
        return {
          imgName: item.name,
          imgUrl: item.url,
        }
      })
      if (spuInfo.id) {
        await reqUpdateSpuInfo(spuInfo)
      } else {
        await reqSaveSpu(spuInfo)
      }
      ElMessage.success('spu操作成功...')
      emits('getScene', 1)
    } else {
      ElMessage.error('提交失败...')
    }
  })
}
</script>

<style></style>
